﻿using System;
using System.Linq.Expressions;
using System.Text;
using AutoMapper;
using CarAppDomain.CarType.Entities;
using CarAppDomain.CarType.IRepository;
using CarAppDomain.Rule.Entities;
using CarAppDomain.Rule.IRepositories;
using CarAppDto.Dtos;
using CarAppDto.Rule.RuleConfigDtos;
using CarAppService.Rule.IServices;
using D.Util.UtilCache;
using D.Util.UtilConfiguration;
using D.Util.UtilExpression;
using D.UtilCore.Dtos;
using D.UtilCore.JwtUtil;
using D.UtilCore.Models;
using D.UtilCore.Utils;
using D.UtilSqlsugarOrm;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace CarAppDomain.Rule.Services
{
    /// <summary>
    /// 规则组成
    /// </summary>
    public class RuleConfigEntityService : BaseService<RuleConfigEntity>, IRuleConfigEntityService
    {
        private readonly IMapper _mapper;
        private readonly ICacheService _cache;
        private readonly IJwtService _tokenService;
        private readonly IRuleConfigEntityRepository _repository;
        private readonly IBrandEntityRepository _repositoryBrand;
        private readonly IHttpContextAccessor _httpContextAccessor;

        /// <summary>
        /// 构造注入
        /// </summary>
        public RuleConfigEntityService(IMapper mapper, ICacheService cache, IJwtService tokenService, IHttpContextAccessor httpContextAccessor, IRuleConfigEntityRepository repository
            ,IBrandEntityRepository brandEntity)
        {
            // 用于base方法
            base._baseDal = repository;
            this._repository = repository;
            _repositoryBrand = brandEntity;
            _cache = cache;
            _mapper = mapper;
            _tokenService = tokenService;
            _httpContextAccessor = httpContextAccessor;
        }

        #region 增删改查


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> AddAsync(ReqAddRuleConfig reqModel)
        {
            var exists = await _repository.ExistsAsync(m => m.No == reqModel.No);
            if (exists)
            {
                return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = "规则编号已存在" };
            }
            if (!string.IsNullOrWhiteSpace(reqModel.BrandId))
            {
                exists = await _repositoryBrand.ExistsAsync(m => m.Id == reqModel.BrandId);
                if (!exists)
                {
                    return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = "品牌信息不存在" };
                }
            }
            var insertEntity = _mapper.Map<ReqAddRuleConfig, RuleConfigEntity>(reqModel);

            //位置解析
            Dictionary<int, char> ruleDetailDic = new Dictionary<int, char>();
            foreach (RuleConfigDetails rule in reqModel.RuleConfigDetailsList)
            {
                string[] postionArry = rule.Position.Split(',');
                if (postionArry.Length != rule.Value.Length)
                    return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Position:{rule.Position}不对等Value:{rule.Value}" };
                char[] valuesArray = rule.Value.ToCharArray();
                for (int i = 0; i < postionArry.Length; i++)
                {
                    int postion;
                    if (!int.TryParse(postionArry[i], out postion))
                        return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Postion：{postionArry[i]}错误" };
                    if (ruleDetailDic.ContainsKey(postion))
                        return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Postion：{postionArry[i]}重复" };
                    else
                        ruleDetailDic.Add(postion, valuesArray[i]);
                }
            }
            ruleDetailDic = ruleDetailDic.OrderBy(x => x.Key).ToDictionary();
            //位置转正则表达式

            insertEntity.RegularExpression = UtilExpression.ConvertRegularExpression(ruleDetailDic);
            insertEntity.DeleteFlag = false;
            insertEntity.CreateTime = DateTime.Now;
            insertEntity.RuleConfigDetails=JsonConvert.SerializeObject(reqModel.RuleConfigDetailsList);
            insertEntity.Id = Guid.NewGuid().ToString();
            var dbres = await _repository.AddAsync(insertEntity);
            return dbres.NormalResponse();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> DeleteAsync(List<string> ids)
        {
            var dbres = await _repository.DeleteAsync(m => ids.Contains(m.Id));
            return dbres.NormalResponse();
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> UpdateAsync(ReqUpdateRuleConfig reqModel)
        {
            var updateEntity = await _repository.GetModelAsync(m => m.Id == reqModel.Id);
            if (updateEntity == null)
            {
                return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = "该信息不存在" };
            }
            var exists = await _repository.ExistsAsync(m =>m.Id!=reqModel.Id&& m.No == reqModel.No);
            if (exists)
            {
                return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = "规则编号信息已存在" };
            }
            if (!string.IsNullOrWhiteSpace(reqModel.BrandId))
            {
                exists = await _repositoryBrand.ExistsAsync(m => m.Id == reqModel.BrandId);
                if (!exists)
                {
                    return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = "品牌信息不存在" };
                }
            }
            //位置解析
            Dictionary<int, char> ruleDetailDic = new Dictionary<int, char>();
            foreach (RuleConfigDetails rule in reqModel.RuleConfigDetailsList)
            {
                string[] postionArry= rule.Position.Split(',');
                if (postionArry.Length != rule.Value.Length)
                    return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Position:{rule.Position}不对等Value:{rule.Value}" };
                char[] valuesArray = rule.Value.ToCharArray();
                for (int i = 0; i < postionArry.Length; i++)
                {
                    int postion;
                    if(! int.TryParse(postionArry[i],out postion))
                        return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Postion：{postionArry[i]}错误" };
                    if (ruleDetailDic.ContainsKey(postion))
                        return new ApiResult<int>() { Code = StatusCodeEnum.Waring, ErrorMsg = $"Postion：{postionArry[i]}重复" };
                    else
                        ruleDetailDic.Add(postion, valuesArray[i]);
                }
            }
            ruleDetailDic = ruleDetailDic.OrderBy(x => x.Key).ToDictionary();
            //位置转正则表达式
            updateEntity.RegularExpression = UtilExpression.ConvertRegularExpression(ruleDetailDic);
     
            updateEntity.No = reqModel.No;
            updateEntity.Name = reqModel.Name;
            updateEntity.BrandId=reqModel.BrandId;
            updateEntity.Descption=reqModel.Descption;
            updateEntity.UpdateTime = DateTime.Now;
            updateEntity.UpdateUser = reqModel.UpdateUser;
            updateEntity.RuleConfigDetails = JsonConvert.SerializeObject(reqModel.RuleConfigDetailsList);
            var dbres = await _repository.UpdateAsync(updateEntity);
            return dbres.NormalResponse();
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResult<RepRuleConfig>> GetAsync(string id)
        {
            var dbres = await _repository.GetModelAsync(m => m.Id == id);
            var res = _mapper.Map<RuleConfigEntity, RepRuleConfig>(dbres);
            return res.GetResponse();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        public async Task<ApiResult<List<RepRuleConfig>>> QueryListAsync(ReqGueryRuleConfigList reqModel)
        {

            Expression<Func<RuleConfigEntity, bool>> where = null;
          
            if (!string.IsNullOrEmpty(reqModel.No))
            {
                where = where.And(where => where.No.Contains(reqModel.No));
            }

            var res = await _repository.GetListAsync(where);
            return res.GetResponse();
        }
        /// <summary>
        /// 获取分页
        /// </summary>
        /// <param name="reqModel"></param>
        /// <returns></returns>
        public async Task<ApiResult<PageModel<RepRuleConfig>>> QueryPagesAsync(ReqQueryRuleConfigPage reqModel)
        {
            Expression<Func<RuleConfigEntity, bool>> where = null;
            if (!string.IsNullOrEmpty(reqModel.No))
            {
                where = where.And(where => where.No.Contains(reqModel.No));
            }
            Expression<Func<RuleConfigEntity, object>> order = null;
            bool orderByAsc = true;
            if (reqModel.Sorts != null && reqModel.Sorts?.Count != 0)
            {
                SortDto sortDtoFrist = reqModel.Sorts.FirstOrDefault();
                string sortField = sortDtoFrist?.Field;
                string sortOrder = sortDtoFrist?.Sort;
                order = ExpressionUtil.GetOrderObjectExpression<RuleConfigEntity>(sortField, sortOrder, ref orderByAsc);
            }
            else
                order = m => m.CreateTime;
            var dbres = await _repository.GetOrderPagesAsync(reqModel.PageSize, reqModel.PageNo, where, order, orderByAsc);

            //var dbres = await _repository.GetOrderPagesAsync(reqModel.PageSize, reqModel.PageNo, where, m => m.CreateTime);
            var res = new PageModel<RepRuleConfig>()
            {
                PageNo = dbres.PageNo,
                PageSize = dbres.PageSize,
                TotalCount = dbres.TotalCount,
                TotalPage = dbres.TotalPage,
                Data = dbres.Data
            };
            return res.GetResponse();
        }
        #endregion 

     
        /// <summary>
        /// 根据VIN码获取规则
        /// </summary>
        /// <param name="VIN"></param>
        /// <returns></returns>

        public async Task<ApiResult<List<RepRuleConfig>>> GetRuleConfigByVINAsync(string VIN)
        {
            var res = await _repository.GetRuleConfigByVINAsync( VIN);
            //var res = _mapper.Map<List<RuleConfigEntity>, List<RepRuleConfig>>(dbres);
            return res.GetResponse();
        }
    }
}
